﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace formats
{
    public class kml : placemarkAbstract
    {
        public kml()
        {
            xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

            content = "<kml xmlns=\"http://earth.google.com/kml/2.2\">";
            contentF = "</kml>";

            document = "<Document>";
            documentF = "</Document>";

            placemark = "<Placemark>";
            placemarkF = "</Placemark>";

            name = "<name>";
            nameF = "</name>";

            description = "<description>";
            descriptionF = "</description>";

            position = "<Point>";
            positionF = "</Point>";

            pLat = "<coordinates>";
            pLatF = "</coordinates>";

            pLong = "";
            pLongF = "";

            pAlt = "";
            pAltF = "";

            data = new List<plm>();
        }

        public override List<plm> read(System.IO.Stream streamIn)
        {
            plm input;

            if (streamIn.Length < 10) return null;
            if (readHeader(streamIn).Equals(xml))    //xml version correct
            {
                if(readHeader(streamIn).Equals(content))    //content header is correct
                {
                    if (readHeader(streamIn).Equals(document))   //corect document header
                    {
                        while (readHeader(streamIn).Equals(placemark))
                        {
                            input = new plm();
                            String inputPlacemark = " ";
                            while (!inputPlacemark.EndsWith(placemarkF))
                            {
                                inputPlacemark += (char)streamIn.ReadByte();
                            };

                            if (inputPlacemark.Contains(name))
                                input.name = inputPlacemark.Substring(inputPlacemark.IndexOf(name) + name.Length, (inputPlacemark.IndexOf(nameF) - (inputPlacemark.IndexOf(name) + name.Length)));
                            else input.name = " ";

                            if (inputPlacemark.Contains(description))
                                input.description = inputPlacemark.Substring(inputPlacemark.IndexOf(description) + description.Length, (inputPlacemark.IndexOf(descriptionF) - (inputPlacemark.IndexOf(description) + description.Length)));
                            else input.description = " ";

                            String pos;
                            if (inputPlacemark.Contains(pLat))
                            {
                                pos = inputPlacemark.Substring(inputPlacemark.IndexOf(pLat) + pLat.Length, (inputPlacemark.IndexOf(pLatF) - (inputPlacemark.IndexOf(pLat) + pLat.Length)));
                                //Longitude, latitude, altitude
                                input.longitude = pos.Substring(0, pos.IndexOf(','));
                                input.latitude = pos.Substring(pos.IndexOf(',') + 1, pos.IndexOf(',', pos.IndexOf(',')+1) - pos.IndexOf(',') -1);
                                input.altitude = pos.Substring(pos.IndexOf(',', pos.IndexOf(',')+1)+1);
                            }
                            else
                                input.longitude = input.latitude = input.altitude = "0";

                            data.Add(input);
                        }
                    }
                    else return null;
                }
                else return null;
            }
            else return null;

            return data;
        }

        private String readHeader(System.IO.Stream streamIn)
        {
            String header = "";
            Char temp;
            do
            {
                temp = (char)streamIn.ReadByte();
                header += temp;
            } while (temp != '>');
            return header.Trim();            
        }

        private String readContent(System.IO.Stream streamIn)
        {
            String content = "";
            Char c;
            while ((c = (char)streamIn.ReadByte()) != '<')
            {
                content += c;
            }
            streamIn.Position = streamIn.Position - 1;
            if (content == " ") return content;
            else return content.Trim();
        }

        public override Boolean write(System.IO.Stream streamOut, List<plm> data)
        {
            System.IO.StreamWriter writer = new System.IO.StreamWriter(streamOut);
            if (!streamOut.CanWrite) return false;
            writer.WriteLine(xml);
            writer.WriteLine(content);
            writer.WriteLine(document);
            foreach (plm item in data)
            {
                writer.WriteLine(placemark);
                writer.WriteLine(name+item.name+nameF);
                writer.WriteLine(description+item.description+descriptionF);
                writer.WriteLine(position+pLat+item.longitude + "," + item.latitude + "," + item.altitude+pLatF+positionF);
                writer.WriteLine(placemarkF);
            }
            writer.WriteLine(documentF);
            writer.WriteLine(contentF);
            writer.Close();
            return true;
        }
    }
}
